#ifndef __CONNECTION_H__
#define __CONNECTION_H__

#include "common.h"
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include "parseHttpMessage.h"

#define LISTEN_NUM 5

#define IO_QUERY_BUFF_MAX_NUM 4096
#define IO_BUFF_MAX_NUM 2
//conn flag
#define CONN_PENDING_READ (1<<0)
#define CONN_PENDING_WRITE (1<<1)
#define CONN_CLOSE_ASAP (1<<2)

#define PROTO_REPLY_CHUNK_BYTES 1024

// struct replyBlock
// {
//     replyBlock()
//     :used_(0)
//     ,size_(0)
//     {
//     }
//     size_t used_;//保存有效数据长度
//     size_t size_;//记录柔性数组数据长度
//     char buf_[];//柔性数组
// };

struct replyBlock
{
    replyBlock(size_t size)
    :used_(0)
    ,size_(size)
    {
    }

    ~replyBlock()
    {
        used_ = 0;
        size_ = 0;
    }

    size_t used_;//保存有效数据长度
    size_t size_;
    char buf_[];
};

typedef int (*ConnectionCallbackFunc)(struct connection* conn);
class connection
{
public:
    connection(int fd = -1);
    ~connection();

    void reset();
    static int Socket();
    static int Bind(int fd, int port);
    static int Listen(int fd);
    static int Accept(int fd, struct sockaddr_in* addr, socklen_t* len);
    static int SetSockOpt(int fd);

    int setNoBlock();
    bool clientHasPendingReplies();
    void processInputBuffer();

    bool hasPendingReplies();

    void addReply(const char* msg, size_t len);
    bool addReplyToBuff(const char* msg, size_t len);
    bool addReplyToList(const char* msg, size_t len);

    int connnSocketSetWriteHandler(ConnectionCallbackFunc func);
public:
    int fd_;
    //保存命令行的缓存
    char query_buf_[IO_QUERY_BUFF_MAX_NUM];
    int querybuf_pos_;
    //保存应答数据缓存
    char buf_[IO_BUFF_MAX_NUM];
    int buf_pos_;
    int sendlen_;

    //读写标志
    int flags_;
    //响应数据先往buff里塞，buff不够往加reply节点
    size_t reply_size_;//所有reply节点size和
    std::list<replyBlock*> reply_;

    HttpEndPoint* endpoint_;

    ConnectionCallbackFunc accept_func_;
    ConnectionCallbackFunc read_func_;
    ConnectionCallbackFunc write_func_;
};


#endif